package com.tanhua.dubbo.api.mongo;

import com.tanhua.dubbo.async.TimeLineService;
import com.tanhua.dubbo.utils.IdWorker;
import com.tanhua.model.mongo.Friend;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.mongo.MovementTimeLine;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.vo.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.scheduling.annotation.Async;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 圈子服务接口实现类
 */
@DubboService
@Slf4j
public class MovementApiImpl implements MovementApi{

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private TimeLineService timeLineService;

    /**
     * 发布动态
     *
     * @param movement
     */
    @Override
    public void addMovement(Movement movement) {
        Long userId = movement.getUserId();//发布动态的用户id
        //获取当前系统时间long
        long nowTime = System.currentTimeMillis();
        //1 保存动态数据  //id(自动生成) pid(推荐系统pid) created(发布时间)
        movement.setId(ObjectId.get());//设置主键id
        movement.setCreated(nowTime);//发布动态时间
        movement.setPid(idWorker.getNextId("movement"));//推荐系统要使用字段 自增长列 从1开始
        mongoTemplate.insert(movement);
        //2 查询好友列表数据
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);
        //3 保持时间线表数据
        timeLineService.addTimeLine(movement,userId,nowTime,friendList);
        log.debug("***********************发布动态成功了*******************");
    }

    /**
     * 圈子-个人动态（我的动态 首页某个佳人动态数据）
     *
     * @param page
     * @param pageSize
     * @param userId
     */
    @Override
    public PageResult<Movement> findPageMovement(Long page, Long pageSize, Long userId) {
        //1查询总记录数
        Query query = new Query();
        query.addCriteria(Criteria.where("userId").is(userId));
        long counts = mongoTemplate.count(query, Movement.class);
        //2当前页面数据
        query.limit(pageSize.intValue()).skip((page-1)*pageSize);
        //2.1 date降序
        query.with(Sort.by(Sort.Direction.DESC,"created"));
        List<Movement> movementList = mongoTemplate.find(query, Movement.class);
        //3返回PageResult
        return new PageResult<>(page,pageSize,counts,movementList);
    }

    /**
     * 圈子-查询好友动态
     *
     * @param page
     * @param pageSize
     * @param userId
     * @return
     */
    @Override
    public PageResult<Movement> findFriendPageMovement(Long page, Long pageSize, Long userId) {
        //1查询时间线表总记录数
        Query query = new Query();
        query.addCriteria(Criteria.where("friendId").is(userId));
        long counts = mongoTemplate.count(query, MovementTimeLine.class);
        //2查询时间线表分页数据
        query.limit(pageSize.intValue()).skip((page-1)*pageSize);
        //2.1 date降序
        query.with(Sort.by(Sort.Direction.DESC,"created"));
        List<MovementTimeLine> movementTimeLines = mongoTemplate.find(query, MovementTimeLine.class);
        //3根据时间线表获取动态ids
        List<Movement> movementList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(movementTimeLines)) {
            List<ObjectId> movementIds = movementTimeLines.stream().map(MovementTimeLine::getMovementId).collect(Collectors.toList());
            //4根据动态ids查询动态表数据
            Query queryMovement = new Query();
            queryMovement.addCriteria(Criteria.where("id").in(movementIds));
            movementList = mongoTemplate.find(queryMovement, Movement.class);
        }
        //5.构造分页对象返回
        return new PageResult<>(page,pageSize,counts,movementList);
    }

    /**
     * 随机产生10个动态数据
     *
     * @return
     */
    @Override
    public List<Movement> randomMovement() {
        //1查询动态总记录数
        Query query = new Query() ;
        long total = mongoTemplate.count(query, Movement.class);
        //2如果记录数小于10 查询所有动态数据
        if(total <= 10){
            return mongoTemplate.findAll(Movement.class);
        }
        //3如果记录数大于10 随机10条
        long start = RandomUtils.nextLong(0,total-9);
        query.limit(10).skip(start);
        //query.addCriteria(Criteria.where("userId").ne("xx"));
        return mongoTemplate.find(query,Movement.class);
    }

    /**
     * 根据pids查询动态数据
     *
     * @param pidList
     * @return
     */
    @Override
    public List<Movement> findByPids(List<Long> pidList) {
        //1构造pids条件
        Query query = new Query(Criteria.where("pid").in(pidList));
        //2执行动态查询
        return mongoTemplate.find(query,Movement.class);
    }

    /**
     * 单条动态
     *
     * @param publishId
     */
    @Override
    public Movement findById(String publishId) {
        return mongoTemplate.findById(new ObjectId(publishId),Movement.class);
    }

}
